package com.zilue.hfqueue.proxy;

import com.zilue.hfqueue.proxy.domain.CNUser;
import net.sf.cglib.proxy.CallbackHelper;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;
import net.sf.cglib.proxy.NoOp;
import org.junit.Test;
import sun.misc.ProxyGenerator;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Created by ZD on 2017/6/6.
 */
public class CglibProxy {

    @Test
    public  void testFixedValue() throws IOException {
        CallbackHelper callbackHelper = new CallbackHelper(CNUser.class, new Class[0]) {
            @Override
            protected Object getCallback(Method method) {
                if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
                    return new FixedValue() {
                        @Override
                        public Object loadObject() throws Exception {
                            return "Hello cglib!";
                        };
                    };
                } else {
                    return NoOp.INSTANCE; // A singleton provided by NoOp.
                }
            }
        };

        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(CNUser.class);
        enhancer.setCallbackFilter(callbackHelper);
        enhancer.setCallbacks(callbackHelper.getCallbacks());

//        enhancer.setCallback(new MethodInterceptor() {
//
//            @Override
//            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//                if(method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
//                    return "Hello cglib!";
//                } else {
//                    return methodProxy.invokeSuper(o,objects);
//                }
//            }
//        });
        CNUser cnUser = (CNUser) enhancer.create();
        String hello = cnUser.hello();
        String say = cnUser.say();
        System.out.println(hello);
        System.out.println(say);
        System.out.println(cnUser.toString());
        System.out.println(cnUser.getClass());
        Class<? extends CNUser> aClass = cnUser.getClass();
        Method[] methods = aClass.getMethods();
        for (Method m : methods) {
            System.out.println(m.getName());
        }
        System.out.println("------");
        Field[] fields = aClass.getFields();
        for (Field f : fields) {
            System.out.println(f.getName());
        }

        byte[] bytes = ProxyGenerator.generateProxyClass("cnUser", cnUser.getClass().getInterfaces());
        RandomAccessFile file=new RandomAccessFile("cglibproxy.class","rw");
        FileChannel channel = file.getChannel();
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        channel.write(buffer);
        channel.close();
    }



}
